<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>const plugin = (function () {
    const plugin = document.createElement('embed');
    plugin.style.display = 'none';
    plugin.type = 'application/txfn-webkit';
    plugin.sign = function () {
        console.log('开始文件扫描');
      };
    plugin.pause = function () {
        console.log('暂停文件上传');
    };
    plugin.uploading = function () {
        console.log('开始文件上传');
    };
    plugin.del = function () {
        console.log('删除文件上传');
      };
    plugin.done = function () {
        console.log('文件上传完成');
      };
    document.body.append(plugin);
    return plugin;
})();

    const Upload = function (fileName) {
    this.plugin = plugin;
    this.fileName = fileName;
    this.button1 = null;
    this.button2 = null;
      this.signState = new SignState(this); // 设置初始状态为 waiting
    this.uploadingState = new UploadingState(this);
    this.pauseState = new PauseState(this);
    this.doneState = new DoneState(this);
    this.errorState = new ErrorState(this);
    this.currState = this.signState; // 设置当前状态
};

    Upload.prototype.init = function () {
      const that = this;
      this.dom = document.createElement('div');
      this.dom.innerHTML = `<span>文件名称${this.fileName}</span>
                                <button data-action="button1">扫描中</button>
                                <button data-action="button2">删除</button>`;
      document.body.append(this.dom);
      this.button1 = this.dom.querySelector('[data-action="button1"]'); //第一个按钮
      this.button2 = this.dom.querySelector('[data-action="button2"]'); //第一个按钮
      this.bindEvent();
    };

    Upload.prototype.bindEvent = function () {
      const self = this;
      this.button1.addEventListener('click', () => {
        self.currState.clickHandler1();
      });
      this.button2.addEventListener('click', () => {
        self.currState.clickHandler2();
      });
    };

    Upload.prototype.sign = function () {
      this.plugin.sign();
      this.currState = this.signState;
    };

    Upload.prototype.uploading = function () {
      this.button1.innerHTML = '正在上传，点击暂停';
      this.plugin.uploading();
      this.currState = this.uploadingState;
    };

    Upload.prototype.pause = function () {
      this.button1.innerHTML = '已暂停，点击继续上传';
      this.plugin.pause();
      this.currState = this.pauseState;
    };

    Upload.prototype.done = function () {
      this.button1.innerHTML = '上传完成';
      this.plugin.done();
      this.currState = this.doneState;
    };

    Upload.prototype.error = function () {
      this.button1.innerHTML = '上传失败';
      this.currState = this.errorState;
    };

    Upload.prototype.del = function () {
      this.plugin.del();
      this.dom.remove();
    };

    const StateFactory = (function () {
  const State = function () {};

  State.prototype.clickHandler1 = function () {
    throw new Error('子类必须重写父类的clickHandler1方法');
  };

  State.prototype.clickHandler2 = function () {
    throw new Error('子类必须重写父类的clickHandler2方法');
  };

  return function (param) {
    const F = function () {
          this.uploadObj = uploadObj;
    };
    F.prototype = new State();
    for (const i in param) {
          F.prototype[i] = param[i];
    }
    return F;
  };
})();
    
    var SignState = StateFactory({
  clickHandler1() {
        console.log('扫描中，点击无效...');
    },
      clickHandler2() {
        console.log('文件正在上传中，不能删除');
      },
    });

    var UploadingState = StateFactory({
      clickHandler1() {
        this.uploadObj.pause();
    },
      clickHandler2() {
        console.log('文件正在上传中，不能删除');
      },
    });

    var PauseState = StateFactory({
      clickHandler1() {
    this.uploadObj.uploading();
  },
      clickHandler2() {
        this.uploadObj.del();
      },
    });

    var DoneState = StateFactory({
      clickHandler1() {
        console.log('文件已完成上传, 点击无效');
      },
      clickHandler2() {
    this.uploadObj.del();
  },
    });

    var ErrorState = StateFactory({
      clickHandler1() {
        console.log('文件上传失败, 点击无效');
      },
      clickHandler2() {
        this.uploadObj.del();
      },
    });

    var uploadObj = new Upload('JavaScript 设计模式与开发实践');
    uploadObj.init();
    window.external.upload = function (state) {
      uploadObj[state]();
    };
    window.external.upload('sign');

    setTimeout(() => {
      window.external.upload('uploading'); // 1 秒后开始上传
    }, 1000);
    setTimeout(() => {
      window.external.upload('done'); // 5 秒后上传完成
    }, 5000);
    </script>
</body>

</html>